home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / dev / sun4.md / devATC.c < prev    next >
C/C++ Source or Header  |  1992-12-18  |  52KB  |  1,887 lines

  1. /*
  2.  * devATC.c --
  3.  *
  4.  *    Driver the for ATC controller.
  5.  *
  6.  * Copyright 1990 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/dev/sun4.md/devATC.c,v 9.2 92/10/23 15:04:35 elm Exp $ SPRITE (Berkeley)";
  18. #endif /* not lint */
  19.  
  20. /*  all include files in /sprite/lib/include unless otherwise specified */
  21.  
  22. #include <sys/types.h>
  23. #include "sprite.h"          
  24. #include "mach.h"            /* /sprite/src/mach/sun4.md */
  25. #include "dev.h"             /* /sprite/src/kernel/dev */
  26. #include "devInt.h"          /* /sprite/src/kernel/dev/sun4.md */
  27. #include "devDiskLabel.h"    /* /sprite/src/kernel/dev */
  28. #include "dbg.h"             /* /sprite/src/kernel/dbg/sun4.md */
  29. #include "vm.h"
  30. #include "sys.h"
  31. #include "sync.h"
  32. #include "fs.h"              /* /sprite/src/kernel/fs/fs.h */
  33. #include "vmMach.h"          /* /sprite/src/lib/include/sun4.md/vmMach.h */
  34. #include "devQueue.h"        /* /sprite/src/kernel/dev */
  35. #include "devBlockDevice.h"  /* /sprite/src/kernel/dev */
  36. #include "devDiskStats.h"    /* /sprite/src/kernel/dev */
  37. #include "stdlib.h"
  38. #include "iopb.h"             
  39. #include "atcreg.h"          
  40. #include "atc.h"
  41. #include "devATC.h"
  42.  
  43.  
  44. /*
  45. #define DEBUG
  46. */
  47.  
  48. static atcDebug = TRUE;
  49. static sentTables = 0;
  50.  
  51. #ifndef    NUM_IOPBS
  52. #define    NUM_IOPBS    MAX_IOPBS    /* # of IOPBs allocated per ctrlr */
  53. #endif
  54.  
  55. #ifndef    RBURSTSZ
  56. #define    RBURSTSZ    8192        /* VME DMA read burst size */
  57. #endif
  58.  
  59. #ifndef    WBURSTSZ
  60. #define    WBURSTSZ    8192        /* VME DMA write burst size */
  61. #endif
  62.  
  63. #ifndef    VMETIMEOUT
  64. #define    VMETIMEOUT    100        /* VME bus timeout (in ms.) */
  65. #endif
  66.  
  67. #ifndef    TD_FLAGS
  68. #define    TD_FLAGS    0           /* primary w/o block mode, by default */
  69. #endif
  70.  
  71. #ifndef NATC
  72. #define NATC   4         
  73. #endif
  74.  
  75. /*
  76. #ifndef ATC_MAX_DISKS
  77. #define ATC_MAX_DISKS   1
  78. #endif
  79. */
  80. #ifndef ATC_MAX_DISKS
  81. #define ATC_MAX_DISKS   (5*7)
  82. #endif
  83.  
  84. #define TOTAL_CYL (900 * 5)
  85. #define HEADS_PER_CYL 14
  86. #define SECTORS_PER_TRACK 48
  87. /*
  88.  * Unit = (3 bits for controller, 6 bits for volume, 4 bits for partition)
  89.  */
  90.  
  91. #define    MAXCTRL        NATC        /* max taken from the configuration */
  92.  
  93. #define MAXVOL        64        /* up to 64 logical volumes */
  94.  
  95. #define    CTRL(m)        (((m)>>10) & 0x7)/* controller number */
  96. #define VOL(m)        (((m)>>4) & 0x3f)/* volume number */
  97.  
  98. #define    DIAG_VOL    63        /* reserved volume for diagnostics */
  99.  
  100. #define SECTOR_SIZE    512
  101.  
  102. /*
  103.  * Define 'AMOD', the address modifier the Array should use for its DMA
  104.  */
  105.  
  106. #define AMOD 0x3d
  107. #define    A24AMOD    0x3d        /* vmea24 single word */
  108. #define A32WAMOD 0x0d
  109. #define A32BAMOD 0x0f            /* vmea32 block mode */
  110. /*
  111.  * Unless I decide to include a buf structure of my own, I need to 
  112.  * change this and identify the special bit soemwhere else!
  113.  * We need a bit in the buffer 'flags' field to mark special commands.
  114.  * The following determines which bit we grab. Newer versions of RISC/os
  115.  * define B_SPECIAL in <sys/buf.h> so we have to be careful here.
  116.  */
  117. #define    B_SPECIAL    0x80000000
  118.  
  119. #define    IS_SPECIAL(bp)    ((bp)->b_flags & B_SPECIAL)
  120.  
  121.  
  122.  
  123. #define GET_ETYPE(e)    (((e)>>24) & 0xff)
  124. #define GET_ESTATUS(e)    (((e)>>16) & 0xff)
  125. #define GET_ECMD(e)    (((e)>>8) & 0xff)
  126. #define GET_ECODE(e)    (((e)>>0) & 0xff)
  127.  
  128.  
  129. /*  Error types */
  130.  
  131. #define ET_CMD_SPEC    0x00
  132. #define ET_CMD_GEN    0x01
  133. #define ET_ENVIRON    0x02
  134. #define ET_INFO        0x03
  135. #define ET_BKD_DIAG     0x04
  136. #define ET_ABORT        0x05
  137. #define ET_INIT         0x06
  138.  
  139. /*  Error status */
  140.  
  141. #define ES_EMPTY    0x00
  142. #define ES_SENSE_VALID    0x01
  143. #define ES_NONFATAL    0x02
  144. #define ES_EXT_VALID    0x04
  145. #define ES_PASS_THRU    0x08
  146.  
  147. /* Error Codes */
  148. /* Generic codes */
  149.  
  150. #define EC_CMD            0x01     /* invalid command */
  151. #define EC_OPTION         0x02     /* invalid option */
  152. #define EC_PRIORITY       0x03     /* invalid priority */
  153. #define EC_LINK           0x04     /* invalid linked_iopb */
  154. #define EC_FLAGS          0x05     /* invlaid flags */
  155. #define EC_ID             0x06     /* invlaid id field */
  156. #define EC_LOG_BLK        0x07     /* invlaid logical block */
  157. #define EC_BYTE_CNT       0x08     /* invlaid byte count */
  158. #define EC_BUFFER         0x09     /* invalid buffer address */
  159. #define EC_BUFADDRMOD     0x0a     /* invalid buffer address modifier */
  160. #define EC_INT_LEVEL      0x0b     /* invalid interrupt level */
  161. #define EC_AUXBUFMOD      0x0c     /* invalid aux buffer modifier */
  162. #define EC_SG_ENTRIES     0x0d     /* invalid scatter-gather entries */
  163. #define EC_AUXBUFSIZE     0x0e     /* invalid aux buffer size */
  164. #define EC_AUXBUFFER      0x0f     /* invalid aux buffer */
  165. #define EC_SG_COUNT       0x10     /* invalid count in sg_struct */
  166. #define EC_SG_BUFFER      0x11     /* invalid buffer in sg_struct */
  167. #define EC_SG_AMOD        0x12     /* invalid addr mod in s.g. entry */
  168.  
  169. #define EC_BFR_AND_SIZE   0x19     /* buffer and size conflict */
  170. #define EC_BFR_AND_SG     0x1a     /* buffer and scatter/gather conflict */
  171. #define EC_BFR_AND_CHKSUM 0x1b     /* buffer and checksum conflict */
  172.  
  173. /* stask.b Error Codes */
  174.  
  175. #define EC_SCSI           0x29     /* a SCSI error occurred */
  176. #define EC_DEV_OFFLINE    0x2a     /* device is offline */
  177. #define EC_DEV_TIMEOUT    0x2b     /* SCSI REQUEST TIMED OUT */
  178. #define EC_DEV_REBUILDING 0x2c     /* device is being rebuilt
  179.  
  180.  
  181.  
  182.  
  183.  
  184. /*
  185.  * The ATC_RAW_READ and ATC_RAW_WRITE commands return sector header
  186.  * information that looks like the following struct.  Again, this
  187.  * is byte-swapped in comparison with the documentation.
  188.  *
  189.  * A raw read is done during boot strap to determine the drive type.
  190.  * The label is read at the same time to determine the disk geometry,
  191.  * and this information is passed back into the controller.
  192.  */
  193. typedef struct ATCSectorHeader {
  194.     /*
  195.      * Byte 1
  196.      */
  197.     char sectorHigh    :2;
  198.     char reserved    :3;
  199.     char cylHigh    :3;
  200.     /*
  201.      * Byte 0
  202.      */
  203.     char cylLow        :8;
  204.     /*
  205.      * Byte 3
  206.      */
  207.     char driveType    :2;
  208.     char sectorLow    :6;
  209.     /*
  210.      * Byte 2
  211.      */
  212.     char head        :8;
  213. } ATCSectorHeader;
  214.  
  215. typedef struct ATCDisk ATCDisk;
  216. typedef struct Request    Request;
  217.  
  218. struct perRequestInfo {
  219.     Request *requestPtr;          /*  pointer to request info */
  220.     Address dmaBuffer;            /*  pointer to dma buffer */
  221.     int dmaBufferSize;            /*  size of dma buffer */
  222.     struct iopbhdr *IOPBPtr;      /*  pointer to IOPB structure for request */
  223.   } perRequestInfo;
  224.  
  225.  
  226. typedef struct ATCController {
  227.     volatile ATCRegs    *regsPtr;    /* Pointer to Controller's registers */
  228.     int            number;        /* Controller number, 0, 1 ... */
  229.     Sync_Semaphore    mutex;        /* Mutex for queue access */
  230.     Sync_Condition    specialCmdWait; /* Condition to wait of for special
  231.                      * commands liked test unit ready and
  232.                      * reading labels. */
  233.     int            numSpecialWaiting; /* Number of processes waiting to 
  234.                         * get access to the controller for
  235.                         * a sync command. */
  236.     DevCtrlQueues    ctrlQueues;    /* Queues of disk attached to the 
  237.                      * controller. */
  238.     ATCDisk            *disks[ATC_MAX_DISKS]; /* Disk attached to the
  239.                              * controller. */
  240.     u_long    flags;        /* controller state information */
  241. #define            F_PRESENT    0x0001    /* device exists */
  242. #define            F_INIT        0x0002    /* device got init. block */
  243. #define            F_NEED_IOPB    0x0004    /* someone waiting for IOPB */
  244. #define            F_IN_USE    0x0008    /* opened for normal I/O */
  245. #define            F_DIAGS        0x0010    /* opened for diagnostics */
  246. #define            F_FIFO_DATA    0x0020    /* FIFO data avail (diags) */
  247.  
  248.     u_long    debug;        /* controller debug flags */
  249. #define            D_DEBUG        0x0001    /* enable most printfs */
  250. #define            D_SINGLE_REQ    0x0002    /* single-request mode */
  251. #define            D_TIMEOUTS    0x0004    /* enable IOPB timeouts */
  252. #define            D_STIMEOUTS    0x0008    /* show timeouts */
  253.  
  254.     int         numActiveIOPBs;         /* number of outstanding IOPBs */
  255.     int         maxActive;              /* most IOPBs ever active at a time */
  256.  
  257.     int            ilev;            /* interrupt level */
  258.     int            ivec;            /* interrupt vector */
  259.  
  260.     int            fifo_data;        /* last byte read (during diags) */
  261.     int            diag_buf[DBUFSZ];    /* buffer for diagnostics */
  262.  
  263.     u_long    vol_sizes[MAXVOL];    /* volume sizes */
  264.     struct dstats   ds;                    /* driver statistics */
  265.  
  266.     struct iopbhdr  *free_iopbs;    /* head of linked IOPB list */
  267.  
  268.     /*
  269.      * IOPBs and their corresponding status blocks are dynamically
  270.      * allocated in the following arrays. Error status for a given
  271.      * IOPB is returned in the status structure of the same index.
  272.      */
  273.     struct    iopbhdr        *iopblist;
  274.     struct    status        *statuslist;
  275.  
  276.     /*
  277.      * The IOPB and status tables contain pointers to the IOPBs and
  278.      * status structures in the arrays above. The host DMAs the
  279.      * following arrays during initialization so it knows where to
  280.      * find everything in host memory.
  281.      */
  282.     struct    iopb_table    *iopb_table;
  283.     struct    status_table    *status_table;
  284.     
  285.     /*
  286.      * The table descriptor contains pointers to the IOPB and status
  287.      * tables as well as some other controller information. We shove
  288.      * this directly through the command FIFO during initialization.
  289.      */
  290.     struct    table_desc    td;    /* the table descriptor */
  291.     
  292.     Address    diag_buf_addr;        /* DMA address of the buffer */
  293.  
  294.     /*
  295.      * This is a pointer to the iopblist array as it is mapped into
  296.      * DMA space.
  297.      */
  298.     struct    iopbhdr    *iopblistp;
  299.     struct    status    *statuslistp;
  300.  
  301.     struct      perRequestInfo   requestInfo[NUM_IOPBS];
  302.     
  303. } ATCController;
  304.  
  305.  
  306.  
  307. struct ATCDisk {
  308.     ATCController            *atcPtr;    /* Back pointer to controller state */
  309.     int                atcDriveType;    /* ATC code for disk */
  310.     int                slaveID;    /* Drive number */
  311.     int                numCylinders;    /* ... on the disk */
  312.     int                numHeads;    /* ... per cylinder */
  313.     int                numSectors;    /* ... on each track */
  314.     DevQueue            queue;
  315.     DevDiskMap            map[DEV_NUM_DISK_PARTS];/* partitions */
  316.     DevDiskStats        *diskStatsPtr;
  317. };
  318.  
  319.  
  320. /*
  321.  * The interface to ATCDisk the outside world views the disk as a 
  322.  * partitioned disk.  
  323.  */
  324. typedef struct PartitionDisk {
  325.     DevBlockDeviceHandle handle; /* Must be FIRST field. */
  326.     int    partition;         /* Partition number on disk. */
  327.     ATCDisk   *diskPtr;          /* Real disk. */
  328. } PartitionDisk;
  329.  
  330. /*
  331.  * Format of request queued for a ATC disk. This request is 
  332.  * built in the ctrlData area of the DevBlockDeviceRequest.
  333.  */
  334.  
  335. struct Request {
  336.     List_Links    queueLinks;    /* For the dev queue modole. */
  337.     char        command;    /* One of the ATC commands */
  338.     char        option;         /* Option qualifies command */
  339.     char        flags;                         
  340.     ATCDisk     *diskPtr;    /* Target disk for request. */
  341.     int         diskAddress;    /* Starting address of request. */
  342.     int        numSectors;    /* Number of sectors to transfer. */
  343.     Address    buffer;        /* Memory to transfer to/from. */
  344.     int        retries;    /* Number of retries on the command. */
  345.     DevBlockDeviceRequest *requestPtr; /* Block device generating this 
  346.                     * request. */
  347. };
  348.  
  349.  
  350. typedef struct _atcIOCParam{
  351.   char    option;
  352.   char    arg;
  353. }atcIOCParam;
  354.  
  355.  
  356. /* 
  357.  * This is the state that needs to be maintained for each request.
  358.  */
  359.  
  360. /*
  361.  * State for each ATC controller.
  362.  */
  363. static ATCController *ATC[MAXCTRL];
  364.  
  365. /*
  366.  * This controlls the time spent busy waiting for the transfer completion
  367.  * when not in interrupt mode.
  368.  */
  369. #define ATC_WAIT_LENGTH    250000
  370.  
  371. /*
  372.  * Constants related to timeouts
  373.  */
  374. #define WSECS   5
  375. #define WSTART  0        /* start timer */
  376. #define WCONT   1        /* continue timer */
  377. #define REQUEST_COUNT 2  /* number of clock ticks until timeout */
  378.  
  379.  
  380. /*
  381.  * SECTORS_PER_BLOCK
  382.  */
  383. #define SECTORS_PER_BLOCK    (FS_BLOCK_SIZE / DEV_BYTES_PER_SECTOR)
  384.  
  385. /*
  386.  * Forward declarations.
  387.  */
  388. extern void        printf();
  389.  
  390. static void        ResetController();
  391. static ReturnStatus    TestDisk();
  392. static ReturnStatus    ReadDiskLabel();
  393. static void        SetupIOPB();
  394. static void         RequestDone();
  395. static void         StartNextRequest();
  396. static void        FillInDiskTransfer();
  397.  
  398.  
  399. /*
  400.  *----------------------------------------------------------------------
  401.  *
  402.  * alloc_iopb --
  403.  *
  404.  *    Start the next request of an ATC controller.
  405.  *
  406.  * Results:
  407.  *    None.
  408.  *
  409.  * Side effects:
  410.  *    None.
  411.  *
  412.  *----------------------------------------------------------------------
  413.  */
  414. struct iopbhdr *
  415. alloc_iopb(atcPtr)
  416.     register ATCController *atcPtr;
  417. {
  418.     struct iopbhdr    *iopb;
  419.  
  420. if (atcDebug){
  421.     
  422.     if (atcDebug) {
  423.       printf("Entered alloc_iopb.\n");
  424.     }
  425.  
  426. }
  427.  
  428.  
  429.     if (atcPtr->free_iopbs == NULL) {
  430.     return NULL;
  431.     }
  432.  
  433.     iopb = atcPtr->free_iopbs;            /* take from head */
  434.     atcPtr->free_iopbs = atcPtr->free_iopbs->next_free;/* update head ptr */
  435.     atcPtr->numActiveIOPBs++;
  436.     if (atcPtr->numActiveIOPBs > atcPtr->maxActive) {
  437.       if (atcDebug){
  438.     printf("New max IOPBs:  %d\n",atcPtr->numActiveIOPBs);
  439.       }
  440.     }
  441.     return iopb;
  442. }
  443.  
  444.  
  445. /*
  446.  *----------------------------------------------------------------------
  447.  *
  448.  * free_iopb --
  449.  *
  450.  *    Start the next request of an ATC controller.
  451.  *
  452.  * Results:
  453.  *    None.
  454.  *
  455.  * Side effects:
  456.  *    None.
  457.  *
  458.  *----------------------------------------------------------------------
  459.  */
  460. static void
  461. free_iopb(atcPtr, iopb)
  462. register ATCController    *atcPtr;
  463. register struct iopbhdr    *iopb;
  464. {
  465.  
  466.     if (atcPtr->free_iopbs == NULL) {    /* list was empty */
  467.         iopb->next_free = NULL;
  468.         atcPtr->free_iopbs = iopb;
  469.         return;
  470.     }
  471.  
  472.     iopb->next_free = atcPtr->free_iopbs;    /* put iopb at head */
  473.  
  474.     atcPtr->free_iopbs = iopb;
  475.     
  476.     if (atcPtr->flags & F_NEED_IOPB) {
  477.         atcPtr->flags &= ~F_NEED_IOPB;
  478.     }
  479.     atcPtr->numActiveIOPBs--;
  480. }
  481.  
  482.  
  483. /*
  484.  *----------------------------------------------------------------------
  485.  *
  486.  * put_fifo --
  487.  *
  488.  *    Start the next request of an ATC controller.
  489.  *
  490.  * Results:
  491.  *    None.
  492.  *
  493.  * Side effects:
  494.  *    None.
  495.  *
  496.  *----------------------------------------------------------------------
  497.  */
  498. static void
  499. put_fifo(atcPtr, data)
  500. register ATCController *atcPtr;
  501. register int    data;
  502. {
  503.   if (atcDebug){
  504.     printf("Entered put_fifo.  Writing 0x%x\n", data & 0xffff);
  505.     if (atcPtr->debug & D_DEBUG)
  506.       printf("put_fifo: writing 0x%x\n", data & 0xffff);
  507.   }
  508.  
  509.     atcPtr->regsPtr->write_fifo = data;
  510. }
  511.  
  512.  
  513. /*
  514.  *----------------------------------------------------------------------
  515.  *
  516.  * get_fifo --
  517.  *
  518.  *    Start the next request of an ATC controller.
  519.  *
  520.  * Results:
  521.  *    None.
  522.  *
  523.  * Side effects:
  524.  *    None.
  525.  *
  526.  *----------------------------------------------------------------------
  527.  */
  528. static int
  529. get_fifo(atcPtr)
  530. register ATCController    *atcPtr;
  531. {
  532.   int returnVal;
  533.  
  534.   if (atcDebug){
  535.     printf("Entered get_fifo.\n");
  536.   }
  537.  
  538.   returnVal = (atcPtr->regsPtr->read_fifo & 0x01ff);
  539.   if (atcDebug){
  540.     printf("Get_fifo returns %x\n",returnVal);
  541.   }
  542.   return(returnVal);
  543. }
  544.  
  545.  
  546. /*
  547.  *----------------------------------------------------------------------
  548.  *
  549.  * send_table --
  550.  *
  551.  *    Start the next request of an ATC controller.
  552.  *
  553.  * Results:
  554.  *    None.
  555.  *
  556.  * Side effects:
  557.  *    None.
  558.  *
  559.  *----------------------------------------------------------------------
  560.  */
  561. void
  562. send_table(atcPtr)
  563. register ATCController *atcPtr;
  564. {
  565.   register int    i;
  566.   register char    *p = (char *) &atcPtr->td;
  567.  
  568.   if (atcDebug){
  569.     printf("Entered send_table; about to send tables to board\n");
  570.   }
  571.  
  572.   MASTER_LOCK(&(atcPtr->mutex));
  573.  
  574.   put_fifo(atcPtr, TABLE_HEADER);
  575.   for (i=0; i < sizeof(struct table_desc) ;i++, p++)
  576.     put_fifo(atcPtr, *p);
  577.  
  578.   MASTER_UNLOCK(&(atcPtr->mutex));
  579.   
  580. }
  581.  
  582.  
  583. /*
  584.  *----------------------------------------------------------------------
  585.  *
  586.  * SendCommand --
  587.  *
  588.  *      Lower level routine to read or write an ATC device.  Use this
  589.  *      to transfer a contiguous set of sectors.    The interface here
  590.  *      is in terms of a particular ATC disk and the command to be
  591.  *      sent.  This routine takes care of mapping its
  592.  *      buffer into the special multibus memory area that is set up for
  593.  *      Sun DMA.
  594.  *
  595.  * Results:
  596.  *    An error code.
  597.  *
  598.  * Side effects:
  599.  *    Those of the command (Read, write etc.)
  600.  *
  601.  *----------------------------------------------------------------------
  602.  */
  603. static void
  604. SendCommand(diskPtr, requestPtr, wait, index)
  605.     ATCDisk      *diskPtr;    /* Unit, type, etc, of disk to send command. */
  606.     Request     *requestPtr;    /* Command request block. */
  607.     Boolean      wait;        /* Wait for the command to complete. */
  608.     int        index;
  609. {
  610.     ATCController *atcPtr    = diskPtr->atcPtr;
  611.     int        diskAddr    = requestPtr->diskAddress;
  612.     int        numSectors    = requestPtr->numSectors;
  613.     Address    address        = requestPtr->buffer;
  614.  
  615.     /*
  616.      * If the command is going to transfer data be relocate the address
  617.      * into DMA space. 
  618.      */
  619.  
  620.     if (atcDebug){
  621.       printf("Entered Send_Command.\n");
  622.     }
  623.  
  624.     SetupIOPB(requestPtr, diskPtr, diskAddr, numSectors, 
  625.            address, &(atcPtr->iopblist[index]));
  626.  
  627.     if (atcDebug){
  628.       printf("Contents of iopb about to be sent to board:\n");
  629.       printf("    command = 0x%x\n",atcPtr->iopblist[index].iopb.command);
  630.       printf("    option = 0x%x\n",atcPtr->iopblist[index].iopb.option);
  631.       printf("    priority = 0x%x\n",atcPtr->iopblist[index].iopb.priority);
  632.       printf("    reserved1 = 0x%x\n",atcPtr->iopblist[index].iopb.reserved1);
  633.       printf("    flags = 0x%x\n",atcPtr->iopblist[index].iopb.flags);
  634.       printf("    log_array = 0x%x\n",atcPtr->iopblist[index].iopb.log_array);
  635.       printf("    reserved2 = 0x%x\n",atcPtr->iopblist[index].iopb.reserved2);
  636.       printf("    id = 0x%x\n",atcPtr->iopblist[index].iopb.id);
  637.       printf("    logical_block = 0x%x\n",atcPtr->iopblist[index].iopb.logical_block);
  638.       printf("    byte_count = 0x%x\n",atcPtr->iopblist[index].iopb.byte_count);
  639.       printf("    buffer = 0x%x\n",atcPtr->iopblist[index].iopb.buffer);
  640.       printf("    buf_addr_mod = 0x%x\n",atcPtr->iopblist[index].iopb.buf_addr_mod);
  641.       printf("    intr_level = 0x%x\n",atcPtr->iopblist[index].iopb.intr_level);
  642.       printf("    intr_vector = 0x%x\n",atcPtr->iopblist[index].iopb.intr_vector);
  643.       
  644.       printf("    auxbuf_mod = 0x%x\n",atcPtr->iopblist[index].iopb.auxbuf_mod);
  645.       printf("    sg_entries = 0x%x\n",atcPtr->iopblist[index].iopb.sg_entries);
  646.       printf("    auxbuf_size = 0x%x\n",atcPtr->iopblist[index].iopb.auxbuf_size);
  647.       printf("    aux_buffer = 0x%x\n",atcPtr->iopblist[index].iopb.aux_buffer);
  648.     }
  649.  
  650.     /*
  651.      * Start up the controller by pushing index of iopb onto fifo.
  652.      */
  653.     put_fifo(atcPtr, index);
  654.  
  655.     if (atcDebug){
  656.       printf("In Send_Command:  Wrote index to down_fifo.\n");
  657.     }
  658.  
  659. }
  660.  
  661.  
  662.  
  663. /*
  664.  *----------------------------------------------------------------------
  665.  *
  666.  * atcEntryAvailProc --
  667.  *
  668.  *    Act upon an entry becomming available in the queue for a
  669.  *    device.. This routine is the Dev_Queue callback function that
  670.  *    is called whenever work becomes available for a device. 
  671.  *    If the controller is not already busy we dequeue and start the
  672.  *    request.
  673.  *
  674.  * Results:
  675.  *    TRUE if the request is processed. FALSE if the request should be
  676.  *    enqueued.
  677.  *
  678.  * Side effects:
  679.  *    Request may be dequeue and submitted to the device. Request callback
  680.  *    function may be called.
  681.  *
  682.  *----------------------------------------------------------------------
  683.  */
  684.  
  685. static Boolean
  686. atcEntryAvailProc(clientData, newRequestPtr) 
  687.    ClientData    clientData;    /* Really the Device this request ready. */
  688.    List_Links *newRequestPtr;    /* The new request. */
  689. {
  690.     register ATCDisk    *diskPtr = (ATCDisk *) clientData ;
  691.     ATCController    *atcPtr = diskPtr->atcPtr;
  692.     register Request    *requestPtr = (Request *) newRequestPtr;
  693.     struct iopbhdr    *iopbhdrPtr;
  694.     int            index;
  695.  
  696.     if (atcDebug){
  697.       printf("Entered atcEntryAvailProc.\n");
  698.     }
  699.  
  700.     if (requestPtr->numSectors == 0) {
  701.     MASTER_UNLOCK(&atcPtr->mutex);
  702.     RequestDone(requestPtr->diskPtr, requestPtr, SUCCESS, 0);
  703.     MASTER_LOCK(&atcPtr->mutex);
  704.     return TRUE;
  705.     }
  706.     
  707. /*  actEntryAvailProc is called with master locks held
  708.     MASTER_LOCK(&atcPtr->mutex);
  709. */
  710.     iopbhdrPtr = alloc_iopb(atcPtr);
  711.     index = iopbhdrPtr->index;
  712. /*
  713.     MASTER_UNLOCK(&atcPtr->mutex);
  714. */
  715.     if (iopbhdrPtr == NULL) {
  716.     return(FALSE);
  717.     }
  718.  
  719.     MASTER_UNLOCK(&atcPtr->mutex);
  720.     SendCommand(diskPtr, requestPtr, FALSE, index);
  721.     MASTER_LOCK(&atcPtr->mutex);
  722.  
  723.     if (atcDebug){
  724.       printf("In atcEntryAvailProc:  Returned from SendCommand.\n");
  725.     }
  726.  
  727.     return(TRUE);
  728. }
  729.  
  730. /*
  731.  *----------------------------------------------------------------------
  732.  *
  733.  * DevATCInit --
  734.  *      Main thing to do here is appropriately malloc everything and
  735.  *      map appropriate stuff into dma space.
  736.  *    Initialize an ATC controller.
  737.  *
  738.  * Results:
  739.  *    A NIL pointer if the controller does not exists. Otherwise a pointer
  740.  *    the the ATCController stucture.
  741.  *
  742.  * Side effects:
  743.  *    Map the controller into kernel virtual space.
  744.  *    Allocate buffer space associated with the controller.
  745.  *    Do a hardware reset of the controller.
  746.  *
  747.  *----------------------------------------------------------------------
  748.  */
  749. ClientData
  750. DevATCInit(cntrlrPtr)
  751.     DevConfigController *cntrlrPtr;    /* Config info for the controller */
  752. {
  753.     ATCController *atcPtr;    /* ATC specific state */
  754.     register volatile ATCRegs *regsPtr;/* Control registers for ATC */
  755.     short x;                /* Used when probing the controller */
  756.     int    i;
  757.     ReturnStatus status;
  758.  
  759.     /*
  760.      * Poke at the controller's registers to see if it works
  761.      * or we get a bus error.  
  762.      * Mach_Probe(int byteCount, Address readAddress, Address writeAddress)
  763.      * returns ReturnStatus.
  764.      */
  765.     regsPtr = (volatile ATCRegs *) cntrlrPtr->address;
  766.  
  767.     if (atcDebug){
  768.       printf("In DevATCInit:  regsPtr = %x\n",regsPtr);
  769.     }
  770.     
  771.     status = Mach_Probe(sizeof(regsPtr->read_fifo),
  772.              (char *) &(regsPtr->read_fifo), (char *) &x);
  773.     if (status != SUCCESS) {
  774.       printf("ATC%d NOT found.\n", cntrlrPtr->controllerID);
  775.       return DEV_NO_CONTROLLER;
  776.     }
  777.  
  778. #ifdef notdef
  779.     /*
  780.      * Don't write into fifo.
  781.      */
  782.     status = Mach_Probe(sizeof(regsPtr->write_fifo), "x",
  783.                 (char *) &(regsPtr->write_fifo));
  784.     if (status != SUCCESS) {
  785.     return DEV_NO_CONTROLLER;
  786.     }
  787. #endif
  788.  
  789.     /*
  790.      * Allocate and initialize the controller state info.
  791.      */
  792.  
  793.  
  794.     atcPtr = (ATCController *)malloc(sizeof(ATCController));
  795.     bzero((char *) atcPtr, sizeof(ATCController));
  796.     ATC[cntrlrPtr->controllerID] = (ATCController *)atcPtr;
  797.  
  798.     atcPtr->regsPtr = regsPtr;
  799.     atcPtr->number = cntrlrPtr->controllerID;
  800.     atcPtr->ivec = cntrlrPtr->vectorNumber;            
  801.     atcPtr->ilev = 3;            
  802.    
  803.     atcPtr->flags = 0;
  804.     atcPtr->debug = D_TIMEOUTS|D_STIMEOUTS;
  805.  
  806.     for (i=0; i < MAXVOL ;i++)
  807.       atcPtr->vol_sizes[i] = 0;
  808.  
  809.     atcPtr->vol_sizes[0] = 10000000;
  810.     
  811.     /*
  812.      * Allocate the mapped DMA memory for the IOPBs and status table
  813.      * entries.  This memory should not be freed unless the controller 
  814.      * is not going to be accessed again.
  815.      */
  816.  
  817. {
  818.     static Address    linkMemAddress[4] =
  819. /*
  820.     {(Address) 0, (Address) 0, (Address) 0, (Address) 0};
  821. */
  822.     {(Address) 0xff9e0000, (Address) 0xff9f0000, (Address) 0, (Address) 0};
  823.     int            bufferSize;
  824.     Address        hostAddr;
  825.     Address        deviceAddr;
  826.     Address        tempBuffer;
  827.     int            addrOffset;
  828.  
  829.     bufferSize = NUM_IOPBS * (sizeof(struct iopbhdr) + sizeof(struct status) +
  830.         sizeof(struct iopb_table) + sizeof(struct status_table));
  831.     if (linkMemAddress[cntrlrPtr->controllerID] == 0) {
  832.     tempBuffer = malloc(bufferSize);
  833.     hostAddr = (Address)VmMach_DMAAlloc(bufferSize, tempBuffer);
  834.     deviceAddr = hostAddr - VMMACH_DMA_START_ADDR;
  835.     if (hostAddr == (Address) NIL) {
  836.         panic("DevATCInit: unable to allocate DMA memory.\n");
  837.     }
  838.     } else {
  839.     deviceAddr = linkMemAddress[cntrlrPtr->controllerID];
  840.     hostAddr = (Address) VmMach_MapInBigDevice(deviceAddr, 0x00010000, 
  841.         VMMACH_TYPE_VME32DATA);
  842.     }
  843.     printf("IOPBs (size:  %d bytes) mapped host=0x%x, device=0x%x\n",
  844.         bufferSize, hostAddr, deviceAddr);
  845.  
  846.     atcPtr->iopblist = (struct iopbhdr *) hostAddr;
  847.     atcPtr->iopblistp = (struct iopbhdr *) deviceAddr;
  848.     addrOffset = NUM_IOPBS * sizeof(struct iopbhdr);
  849.  
  850.     atcPtr->statuslist = (struct status *) (hostAddr + addrOffset);
  851.     atcPtr->statuslistp = (struct status *) (deviceAddr + addrOffset);
  852.     addrOffset += NUM_IOPBS * sizeof(struct status);
  853.  
  854.     atcPtr->iopb_table = (struct iopb_table *) (hostAddr + addrOffset);
  855.     atcPtr->td.iopb_list = (struct iopb_table *) (deviceAddr + addrOffset);
  856.     addrOffset += NUM_IOPBS * sizeof(struct iopb_table);
  857.  
  858.     atcPtr->status_table = (struct status_table *) (hostAddr + addrOffset);
  859.     atcPtr->td.status_list = (struct status_table *) (deviceAddr + addrOffset);
  860.  
  861.     atcPtr->td.vme_timeout = VMETIMEOUT;
  862.     atcPtr->td.iopb_list_mod = AMOD;
  863.     atcPtr->td.num_iopbs = NUM_IOPBS;
  864.     atcPtr->td.status_list_mod = AMOD;
  865.     atcPtr->td.flags = TD_FLAGS;
  866.     atcPtr->td.reserved = 0;
  867.     atcPtr->td.rdma_burst_sz = RBURSTSZ;
  868.     atcPtr->td.wdma_burst_sz = WBURSTSZ;
  869.  
  870.     for (i=0; i < NUM_IOPBS; i++) {
  871.       atcPtr->iopb_table[i].iopb_ptr = &atcPtr->iopblistp[i].iopb;
  872.       atcPtr->iopb_table[i].iopb_addr_mod = AMOD;
  873.       atcPtr->status_table[i].status_ptr = &atcPtr->statuslistp[i];
  874.       atcPtr->status_table[i].status_addr_mod = AMOD;
  875.     }
  876.  
  877.     atcPtr->numActiveIOPBs = 0;
  878.     atcPtr->maxActive = 0;
  879.     atcPtr->free_iopbs = NULL;
  880.     for (i=0; i < NUM_IOPBS ;i++) {
  881.       atcPtr->iopblist[i].index = i;
  882.       free_iopb(atcPtr, &atcPtr->iopblist[i]);
  883.     }
  884. }
  885.   
  886.     if (atcDebug){
  887.       printf("table_desc.iopb_list       = 0x%x\n", atcPtr->td.iopb_list);
  888.       printf("table_desc.status_list     = 0x%x\n", atcPtr->td.status_list);
  889.       printf("table_desc.iopb_list_mod   = 0x%x\n", AMOD);
  890.       printf("table_desc.status_list_mod = 0x%x\n", AMOD);
  891.       printf("table_desc.num_iopbs       = %d\n", NUM_IOPBS);
  892.     }
  893.  
  894.     atcPtr->flags |= F_PRESENT;
  895.  
  896.     Sync_SemInitDynamic(&atcPtr->mutex,"Dev:ATC mutex");
  897.     atcPtr->numSpecialWaiting = 0;
  898.     atcPtr->ctrlQueues =Dev_CtrlQueuesCreate(&atcPtr->mutex, atcEntryAvailProc);
  899.  
  900.     for (i = 0 ; i < ATC_MAX_DISKS ; i++) {
  901.      atcPtr->disks[i] =  (ATCDisk *) NIL;
  902.     }
  903.  
  904.     return( (ClientData) atcPtr);
  905. }
  906.  
  907. /*
  908.  *----------------------------------------------------------------------
  909.  *
  910.  * ReleaseProc --
  911.  *    Device release proc for controller.
  912.  *
  913.  * Results:
  914.  *    None.
  915.  *
  916.  * Side effects:
  917.  *    None.
  918.  *
  919.  *----------------------------------------------------------------------
  920.  */
  921. static ReturnStatus
  922. ReleaseProc(handlePtr)
  923.     DevBlockDeviceHandle    *handlePtr; /* Handle pointer of device. */
  924. {
  925.  
  926.     PartitionDisk    *pdiskPtr = (PartitionDisk *) handlePtr;
  927.  
  928.     if (atcDebug){
  929.       printf("Entered ReleaseProc.\n");
  930.     }
  931.  
  932.     free((char *) pdiskPtr);
  933.     return SUCCESS;
  934. }
  935.  
  936.  
  937. /*
  938.  *----------------------------------------------------------------------
  939.  *
  940.  * IOControlProc --
  941.  *
  942.  *      Do a special operation on a raw SMD Disk.
  943.  *      Need to put atc iocontrols in here.  
  944.  *
  945.  * Results:
  946.  *      None.
  947.  *
  948.  * Side effects:
  949.  *      None.
  950.  *
  951.  *----------------------------------------------------------------------
  952.  */
  953.  
  954. /*ARGSUSED*/
  955. static ReturnStatus
  956. IOControlProc(handlePtr, ioctlPtr, replyPtr)
  957.     DevBlockDeviceHandle    *handlePtr; /* Handle pointer of device. */
  958.     Fs_IOCParam *ioctlPtr;    /* Standard I/O Control parameter block */
  959.     Fs_IOReply *replyPtr;    /* Size of outBuffer and returned signal */
  960. {
  961.     PartitionDisk    *pdiskPtr    = (PartitionDisk *) handlePtr;
  962.     register ATCDisk    *diskPtr    = pdiskPtr->diskPtr;
  963.     ATCController       *atcPtr         = diskPtr->atcPtr;
  964.  
  965. /*
  966.     atcIOCParam         *atcIOCParamPtr = (atcIOCParam *)ioctlPtr->inBuffer;
  967. */
  968.     DevBlockDeviceRequest *reqPtr       = (DevBlockDeviceRequest *)ioctlPtr->inBuffer;
  969.     int  amtTransfer;
  970.  
  971.     if (atcDebug){
  972.       printf("Entered IOControlProc.\n");
  973.     }
  974.  
  975.  
  976.      switch (ioctlPtr->command) {
  977.  
  978.      case IOC_ATC_DEBUG_ON:
  979.        atcDebug = TRUE;
  980.        return(SUCCESS);
  981.        break;
  982.  
  983.      case IOC_ATC_DEBUG_OFF:
  984.        atcDebug = FALSE;
  985.        return(SUCCESS);
  986.        break;
  987.  
  988.      case CMD_READ_CONF:
  989.        return(SUCCESS);
  990.        break;
  991.  
  992.      case CMD_WRITE_CONF:
  993.        return(SUCCESS);
  994.        break;
  995.  
  996.      case IOC_REPOSITION:
  997.        /*
  998.     * Reposition is ok
  999.     */
  1000.        return(SUCCESS);
  1001.        break;
  1002.        /*
  1003.     * No disk specific bits are set this way.
  1004.     */
  1005.        
  1006. /*
  1007.      case IOC_DEV_ATC_READXBUS:
  1008.        break;
  1009.  
  1010.      case IOC_DEV_ATC_WRITEXBUS:
  1011.        break;
  1012.  
  1013.      case IOC_DEV_ATC_SSTATS:
  1014.        return(SUCCESS);
  1015.        break;
  1016.        
  1017.      case IOC_DEV_ATC_CSTATS:
  1018.        return(SUCCESS);
  1019.        break;
  1020. */
  1021.  
  1022.      case IOC_DEV_ATC_IO:
  1023.        if (atcDebug){
  1024.      printf("operation = %d\n",reqPtr->operation);
  1025.      printf("startAddress = 0x%x\n",reqPtr->startAddress);
  1026.      printf("startAddrHigh = 0x%x\n",reqPtr->startAddrHigh);
  1027.      printf("bufferLen = %d\n",reqPtr->bufferLen);
  1028.      printf("buffer = 0x%x\n",reqPtr->buffer);
  1029.        }
  1030.        Dev_BlockDeviceIOSync(handlePtr, reqPtr, &amtTransfer);
  1031.        if (amtTransfer != reqPtr->bufferLen){
  1032.      return(FAILURE);
  1033.        } else {
  1034.      return(SUCCESS);
  1035.        }
  1036.        break;
  1037.  
  1038.      case ATC_RESET:
  1039.        ResetController(atcPtr);
  1040.        return(SUCCESS);
  1041.        break;
  1042.  
  1043.      default:
  1044.        return(GEN_INVALID_ARG);
  1045.      }
  1046. }
  1047.  
  1048. /*
  1049.  *----------------------------------------------------------------------
  1050.  *
  1051.  * BlockIOProc --
  1052.  *    Start a block IO operations on an ATC board.
  1053.  *      Remember that we are treating the queue as a single queue for
  1054.  *      the entire board.
  1055.  *
  1056.  * Results:
  1057.  *    None.
  1058.  *
  1059.  * Side effects:
  1060.  *    None.
  1061.  *
  1062.  *----------------------------------------------------------------------
  1063.  */
  1064. static ReturnStatus
  1065. BlockIOProc(handlePtr, requestPtr) 
  1066.     DevBlockDeviceHandle    *handlePtr;
  1067.     DevBlockDeviceRequest    *requestPtr;
  1068. {
  1069.     PartitionDisk    *pdiskPtr    = (PartitionDisk *) handlePtr;
  1070.     register ATCDisk    *diskPtr    = pdiskPtr->diskPtr;
  1071.     register Request    *reqPtr        = (Request *) requestPtr->ctrlData;
  1072.  
  1073.     if (atcDebug){
  1074.       printf("Entered BlockIOProc.\n");
  1075.     }
  1076.  
  1077.  
  1078.     if (requestPtr->operation == FS_READ) {
  1079.     reqPtr->command = CMD_READ;
  1080.     reqPtr->option = 0;
  1081.     reqPtr->flags = 0;
  1082.     } else {
  1083.     reqPtr->command = CMD_WRITE;
  1084.     reqPtr->option = 0;
  1085.     reqPtr->flags = 0;
  1086.     }
  1087.  
  1088.     reqPtr->diskPtr = diskPtr;
  1089.     FillInDiskTransfer(pdiskPtr, requestPtr->startAddress, 
  1090.             (unsigned) requestPtr->bufferLen,
  1091.             &(reqPtr->diskAddress), &(reqPtr->numSectors));
  1092.     reqPtr->buffer = requestPtr->buffer;
  1093.     reqPtr->retries = 0;
  1094.     reqPtr->requestPtr = requestPtr;
  1095.     Dev_QueueInsert(diskPtr->queue, (List_Links *) reqPtr);
  1096.     return SUCCESS;
  1097. }
  1098.  
  1099. /*
  1100.  *----------------------------------------------------------------------
  1101.  *
  1102.  * atcIdleCheck --
  1103.  *
  1104.  *    Routine for the Disk Stats module to use to determine the idleness
  1105.  *    for a disk.   I have changed this to look for the F_INUSE or F_DIAG
  1106.  *      flags for the controller.  These tell whether the controller is in
  1107.  *      use for normal I/O or for diagnostics.
  1108.  *
  1109.  * Results:
  1110.  *    TRUE if the disk pointed to by clientData is idle, FALSE otherwise.
  1111.  *
  1112.  * Side effects:
  1113.  *    None.
  1114.  *
  1115.  *----------------------------------------------------------------------
  1116.  */
  1117.  
  1118. static Boolean
  1119. atcIdleCheck(clientData, diskStatsPtr) 
  1120.     ClientData    clientData;
  1121.     DevDiskStats    *diskStatsPtr;    /* Unused for ATC. */
  1122. {
  1123.     ATCDisk *diskPtr = (ATCDisk *) clientData;
  1124.  
  1125.     return (!(diskPtr->atcPtr->flags & F_PRESENT));
  1126. }
  1127.  
  1128.  
  1129. /*
  1130.  *----------------------------------------------------------------------
  1131.  *
  1132.  * DevATCDiskAttach --
  1133.  *
  1134.  *      Initialize a device hanging off an ATC controller. 
  1135.  *
  1136.  * Results:
  1137.  *    A DevBlockDeviceHanlde for this disk.
  1138.  *
  1139.  * Side effects:
  1140.  *    Disks:  The label sector is read and the partitioning of
  1141.  *    the disk is set up.  The partitions correspond to device
  1142.  *    files of the same type but with different unit number.
  1143.  *
  1144.  *----------------------------------------------------------------------
  1145.  */
  1146. DevBlockDeviceHandle *
  1147. DevATCDiskAttach(devicePtr)
  1148.     Fs_Device        *devicePtr;    /* Device to attach. */
  1149. {
  1150.     ReturnStatus error;
  1151.     ATCController       *atcPtr;    /* ATC specific controller state */
  1152.     register ATCDisk    *diskPtr;
  1153.     PartitionDisk    *pdiskPtr;    /* Partitioned disk pointer. */
  1154.     int        controllerID;
  1155.     int        diskNumber;
  1156.  
  1157.     if (atcDebug){
  1158.       printf("Entered DevATCDiskAttach.\n");
  1159.     }
  1160.  
  1161.     controllerID = CTRL(devicePtr->unit);   
  1162.     diskNumber = VOL(devicePtr->unit);
  1163.     
  1164.     if (atcDebug){
  1165.       printf("AtcDiskAttach unit 0x%x ctrlr %d disk %d\n",
  1166.          devicePtr->unit, controllerID, diskNumber);
  1167.     }
  1168.  
  1169.     atcPtr = (ATCController *)ATC[controllerID];
  1170.  
  1171.  
  1172.     if (atcPtr == (ATCController *)NIL ||
  1173.     atcPtr == (ATCController *)0 ||
  1174.     diskNumber > MAXVOL) {
  1175.     return ((DevBlockDeviceHandle *) NIL);
  1176.     }
  1177.  
  1178.     if (!sentTables){
  1179.       ResetController(atcPtr);
  1180.       sentTables = 1;
  1181.       MACH_DELAY(100000);
  1182.     }
  1183.  
  1184.     /*
  1185.      * Set up a slot in the disk list. We do a malloc before we grab the
  1186.      * MASTER_LOCK().
  1187.      */
  1188.     diskPtr = (ATCDisk *) malloc(sizeof(ATCDisk));
  1189.     bzero((char *) diskPtr, sizeof(ATCDisk));
  1190.     diskPtr->atcPtr = atcPtr;
  1191.     diskPtr->atcDriveType = 0;
  1192.     diskPtr->slaveID = diskNumber;
  1193.     diskPtr->queue = Dev_QueueCreate(atcPtr->ctrlQueues, 1, 
  1194.                 DEV_QUEUE_FIFO_INSERT, (ClientData) diskPtr);
  1195.  
  1196.     MASTER_LOCK(&(atcPtr->mutex));
  1197.     if (atcPtr->disks[diskNumber] == (ATCDisk *) NIL) {
  1198.     /*
  1199.      * See if the disk is really there.
  1200.      */
  1201.     atcPtr->disks[diskNumber] = diskPtr;
  1202.  
  1203.     error = TestDisk(atcPtr, diskPtr);
  1204.     if (error == SUCCESS) {
  1205.         /*
  1206.          * Look at the zero'th sector for disk information.  This also
  1207.          * sets the drive type with the controller.
  1208.          */
  1209.         error = ReadDiskLabel(atcPtr, diskPtr);
  1210.     }
  1211.  
  1212.     if (error != SUCCESS) {
  1213.         atcPtr->disks[diskNumber] =  (ATCDisk *) NIL;
  1214.         MASTER_UNLOCK(&(atcPtr->mutex));
  1215.         Dev_QueueDestroy(diskPtr->queue);
  1216.         free((Address)diskPtr);
  1217.         return ((DevBlockDeviceHandle *) NIL);
  1218.     } 
  1219.     MASTER_UNLOCK(&(atcPtr->mutex));
  1220.     /* 
  1221.      * Register the disk with the disk stats module. 
  1222.      */
  1223.     {
  1224.         Fs_Device    rawDevice;
  1225.         char    name[128];
  1226.         extern int    sprintf();
  1227.  
  1228.         rawDevice =  *devicePtr;
  1229.         rawDevice.unit = rawDevice.unit & ~0xf;
  1230.         (void) sprintf(name, "atc%d-%d", atcPtr->number, diskPtr->slaveID);
  1231.         diskPtr->diskStatsPtr = DevRegisterDisk(&rawDevice, name, 
  1232.                    atcIdleCheck, (ClientData) diskPtr);
  1233.     }
  1234.     } else {
  1235.     /*
  1236.      * The disk already exists. Use it.
  1237.      */
  1238.     MASTER_UNLOCK(&(atcPtr->mutex));
  1239.     Dev_QueueDestroy(diskPtr->queue);
  1240.     free((Address)diskPtr);
  1241.     diskPtr = atcPtr->disks[diskNumber];
  1242.     }
  1243.     pdiskPtr = (PartitionDisk *) malloc(sizeof(*pdiskPtr));
  1244.     bzero((char *) pdiskPtr, sizeof(*pdiskPtr));
  1245.     pdiskPtr->handle.blockIOProc = BlockIOProc;
  1246.     pdiskPtr->handle.IOControlProc = IOControlProc;
  1247.     pdiskPtr->handle.releaseProc = ReleaseProc;
  1248.     pdiskPtr->handle.minTransferUnit = DEV_BYTES_PER_SECTOR;
  1249.     pdiskPtr->handle.maxTransferSize = 100*1024;
  1250.     pdiskPtr->partition = DISK_IS_PARTITIONED(devicePtr) ? 
  1251.                     DISK_PARTITION(devicePtr) : 
  1252.                     WHOLE_DISK_PARTITION;
  1253.     pdiskPtr->diskPtr = diskPtr;
  1254.     return ((DevBlockDeviceHandle *) pdiskPtr);
  1255. }
  1256.  
  1257.  
  1258.  
  1259. /*
  1260.  *----------------------------------------------------------------------
  1261.  *
  1262.  * ResetController --
  1263.  *
  1264.  *    Reset the controller.  This is done by sending down the descriptor
  1265.  *    table to the board through the FIFO.
  1266.  *
  1267.  * Results:
  1268.  *    None.
  1269.  *
  1270.  * Side effects:
  1271.  *    Reset the controller.
  1272.  *
  1273.  *----------------------------------------------------------------------
  1274.  */
  1275. static void
  1276. ResetController(atcPtr)
  1277.     volatile ATCController *atcPtr;
  1278. {
  1279.  
  1280.   if (atcDebug){
  1281.     printf("Entered ResetController.\n");
  1282.   }
  1283.  
  1284.  
  1285.   send_table(atcPtr);
  1286. }
  1287.  
  1288. /*
  1289.  *----------------------------------------------------------------------
  1290.  *
  1291.  * TestDisk --
  1292.  *    Get a controller's status to see if it exists.  We do not
  1293.  *      test individual disks in this controller.
  1294.  *
  1295.  * Results:
  1296.  *    SUCCESS if the device is ok, DEV_OFFLINE otherwise.
  1297.  *
  1298.  * Side effects:
  1299.  *    none.
  1300.  *
  1301.  *----------------------------------------------------------------------
  1302.  */
  1303. static ReturnStatus
  1304. TestDisk(atcPtr, diskPtr)
  1305.     ATCController *atcPtr;
  1306.     ATCDisk *diskPtr;
  1307. {
  1308.  
  1309.   if (atcDebug){
  1310.     printf("Entered TestDisk.\n");
  1311.   }
  1312.  
  1313.  
  1314.   if (atcPtr->flags & F_PRESENT){
  1315.     return(SUCCESS);
  1316.   } else {
  1317.     return(DEV_OFFLINE);
  1318.   }
  1319. }
  1320.  
  1321. /*
  1322.  *----------------------------------------------------------------------
  1323.  *
  1324.  * ReadDiskLabel --
  1325.  *
  1326.  *    Read the label of the disk and record the partitioning info.
  1327.  *
  1328.  *      For the ATC driver, this is a dummy routine which currently
  1329.  *      specifies a single partition containing all the data available.
  1330.  *
  1331.  * Results:
  1332.  *    None.
  1333.  *
  1334.  * Side effects:
  1335.  *    Define the disk partitions that determine which part of the
  1336.  *    disk each different disk device uses.
  1337.  *
  1338.  *----------------------------------------------------------------------
  1339.  */
  1340. static ReturnStatus
  1341. ReadDiskLabel(atcPtr, diskPtr)
  1342.     ATCController *atcPtr;
  1343.     ATCDisk *diskPtr;
  1344. {
  1345.   int part;
  1346.  
  1347.   if (atcDebug){
  1348.     printf("Entered ReadDiskLabel.\n");
  1349.   }
  1350.  
  1351.   diskPtr->atcDriveType = 1;
  1352.   diskPtr->numCylinders = TOTAL_CYL;
  1353.   diskPtr->numHeads = HEADS_PER_CYL;
  1354.   diskPtr->numSectors = SECTORS_PER_TRACK;
  1355.     
  1356.   for (part = 0; part < DEV_NUM_DISK_PARTS; part++) {
  1357.     diskPtr->map[part].firstCylinder = 0;
  1358.     diskPtr->map[part].numCylinders = TOTAL_CYL;
  1359.   }
  1360.   return(SUCCESS);
  1361. }
  1362.  
  1363.  
  1364. /*
  1365.  *----------------------------------------------------------------------
  1366.  *
  1367.  *  FillInDiskTransfer
  1368.  *    Fill in the disk address and number of sectors of a command.
  1369.  *
  1370.  * Results:
  1371.  *    None.
  1372.  *
  1373.  * Side effects:
  1374.  *    The number of sectors to transfer gets trimmed down if it would
  1375.  *    cross into the next partition.
  1376.  *
  1377.  *----------------------------------------------------------------------
  1378.  */
  1379. static void
  1380. FillInDiskTransfer(pdiskPtr, startAddress, length, diskAddrPtr, numSectorsPtr)
  1381.     PartitionDisk    *pdiskPtr;    /* Target Disk Partition. */
  1382.     unsigned int    startAddress;    /* Starting offset in bytes.*/
  1383.     unsigned int    length;        /* Length in bytes. */
  1384.     int         *diskAddrPtr;    /* Disk disk address of
  1385.                      * the first sector to transfer */
  1386.     int *numSectorsPtr;            /* The number
  1387.                      * of sectors to transferred. */
  1388. {
  1389.     ATCDisk *diskPtr;    /* State of the disk */
  1390.     int totalSectors;    /* The total number of sectors to transfer */
  1391.     int lastSector;    /* Last sector of the partition */
  1392.     int startSector;    /* The first sector of the transfer */
  1393.     int    part;        /* Partition number. */
  1394.     int    cylinderSize;    /* Size of a cylinder in sectors. */
  1395.  
  1396.     if (atcDebug){
  1397.       printf("Entered FillInDiskTransfer.\n");
  1398.     }
  1399.  
  1400.     diskPtr = pdiskPtr->diskPtr;
  1401.     part = pdiskPtr->partition;
  1402.     cylinderSize = diskPtr->numHeads * diskPtr->numSectors;
  1403.     /*
  1404.      * Do bounds checking to keep the I/O within the partition.
  1405.      * sectorZero is the sector number of the first sector in the partition,
  1406.      * lastSector is the sector number of the last sector in the partition.
  1407.      * (These sector numbers are relative to the start of the partition.)
  1408.      */
  1409.     lastSector = diskPtr->map[part].numCylinders * cylinderSize - 1;
  1410.     totalSectors = length/DEV_BYTES_PER_SECTOR;
  1411.  
  1412.     startSector = startAddress / DEV_BYTES_PER_SECTOR;
  1413.  
  1414.     if (startSector > lastSector) {
  1415.     /*
  1416.      * The offset is past the end of the partition.
  1417.      */
  1418.     *numSectorsPtr = 0;
  1419.     printf("Warning: ATCDiskIO: Past end of partition %d\n",
  1420.                 part);
  1421.     return;
  1422.     } else if ((startSector + totalSectors - 1) > lastSector) {
  1423.     /*
  1424.      * The transfer is at the end of the partition.  Reduce the
  1425.      * sector count so there is no overrun.
  1426.      */
  1427.     totalSectors = lastSector - startSector + 1;
  1428.     printf("Warning: ATCDiskIO: Overrun partition %d\n",
  1429.                 part);
  1430.     }
  1431.     (*diskAddrPtr) = startSector;
  1432.     (*diskAddrPtr) += diskPtr->map[part].firstCylinder * cylinderSize;
  1433.  
  1434.     *numSectorsPtr = totalSectors;
  1435.     return;
  1436. }
  1437.  
  1438. /*
  1439.  *----------------------------------------------------------------------
  1440.  *
  1441.  * SetupIOPB --
  1442.  *
  1443.  *      What to do about the bp structure, and all the info passed to/from it?
  1444.  *
  1445.  *      Setup a IOPB for a command.  The IOPB can then
  1446.  *      be passed to SendCommand.  It specifies everything the
  1447.  *    controller needs to know to do a transfer, and it is updated
  1448.  *    with status information upon completion.
  1449.  *
  1450.  * Results:
  1451.  *    None.
  1452.  *
  1453.  * Side effects:
  1454.  *    Set the various fields in the control block.
  1455.  *
  1456.  *----------------------------------------------------------------------
  1457.  */
  1458. static void
  1459. SetupIOPB(requestPtr, diskPtr, diskAddr, numSectors, address, IOPBPtr)
  1460.      Request *requestPtr;
  1461.      ATCDisk *diskPtr;                /* Spefifies unit, drive type, etc */
  1462.      register int diskAddr;            /* Disk address of operation*/
  1463.      int numSectors;            /* Number of sectors to transfer */
  1464.      register Address address;        /* Address of the buffer */
  1465.      struct iopbhdr *IOPBPtr;       /* I/O Parameter Block  */
  1466. {
  1467.     ATCController    *atcPtr        = diskPtr->atcPtr;
  1468.     int            logicalBlock    = diskAddr;
  1469.     int            byteCount    = numSectors * DEV_BYTES_PER_SECTOR;
  1470.     int            index        = IOPBPtr->index;
  1471.     char              cmd             = requestPtr->command;
  1472.     int            bufSize        = DEV_BYTES_PER_SECTOR  * numSectors;
  1473.     Address        dmaAddress;
  1474.     int            amod;
  1475.  
  1476.     if (atcDebug){
  1477.       printf("Entered SetupIOPB.\n");
  1478.     }
  1479.     
  1480.     /*
  1481.      * Determine DMA address and address modifier.
  1482.      */
  1483.     if (VmMachIsXbusMem(address)) {
  1484.     amod = A32BAMOD;
  1485.     dmaAddress = address;
  1486.     } else {
  1487.     amod = A32WAMOD;
  1488.     if (bufSize > 0) {
  1489.         dmaAddress = (Address) VmMach_32BitDMAAlloc(bufSize, address);
  1490.     } else {
  1491.         dmaAddress = VMMACH_DMA_START_ADDR;
  1492.     }
  1493.     if ((unsigned) dmaAddress > (unsigned)VMMACH_DMA_START_ADDR) {
  1494.         dmaAddress -= VMMACH_DMA_START_ADDR;
  1495.     }
  1496.     }
  1497.     if (atcDebug){
  1498.         printf("dmaBuffer size %d sectors mapped to dma address 0x%x\n",
  1499.         numSectors, dmaAddress);
  1500.     }
  1501.  
  1502.     bzero((char *) &(IOPBPtr->iopb), sizeof(struct iopb));
  1503.     IOPBPtr->bp            = NULL;            /* we are not using this */
  1504.     IOPBPtr->iopb.command    = requestPtr->command;
  1505.     IOPBPtr->iopb.option    = requestPtr->option;
  1506.     IOPBPtr->iopb.reserved1    = 0x7f;
  1507.     IOPBPtr->iopb.flags        = requestPtr->flags;
  1508.     IOPBPtr->iopb.log_array    = 1;                /* logical array number */
  1509.     IOPBPtr->iopb.reserved2    = 0;
  1510.     IOPBPtr->iopb.buffer    = dmaAddress;
  1511.     IOPBPtr->iopb.buf_addr_mod    = amod;
  1512.     IOPBPtr->iopb.intr_level    = atcPtr->ilev;
  1513.     IOPBPtr->iopb.intr_vector    = atcPtr->ivec;
  1514.     IOPBPtr->iopb.auxbuf_mod    = 0;
  1515.     IOPBPtr->iopb.sg_entries    = 0;            /* no scatter-gather */
  1516.     IOPBPtr->iopb.auxbuf_size    = 0;
  1517.     IOPBPtr->iopb.aux_buffer    = 0;
  1518.     
  1519.     /*  
  1520.      *  byte_count used to be byteCount
  1521.      */
  1522.  
  1523.     switch (cmd) {
  1524.     case CMD_READ:
  1525.       IOPBPtr->iopb.byte_count = byteCount;
  1526.       IOPBPtr->iopb.id = diskPtr->slaveID;
  1527.       IOPBPtr->iopb.logical_block = logicalBlock;
  1528.       break;    
  1529.     case CMD_WRITE:
  1530.       IOPBPtr->iopb.byte_count = byteCount;
  1531.       IOPBPtr->iopb.id = diskPtr->slaveID;
  1532.       IOPBPtr->iopb.logical_block = logicalBlock;
  1533.       break;
  1534.     default:
  1535.       printf("setup_iopb: invalid command %d\n", cmd);
  1536.       free_iopb(atcPtr, IOPBPtr);
  1537.     }
  1538.  
  1539.     atcPtr->requestInfo[index].requestPtr = requestPtr;
  1540.     atcPtr->requestInfo[index].dmaBuffer = dmaAddress;
  1541.     atcPtr->requestInfo[index].dmaBufferSize = byteCount;
  1542.     atcPtr->requestInfo[index].IOPBPtr = IOPBPtr;
  1543. }
  1544.  
  1545.  
  1546.  
  1547. /*
  1548.  *----------------------------------------------------------------------
  1549.  *
  1550.  * reportError --
  1551.  *
  1552.  * Results:
  1553.  *
  1554.  * Side effects:
  1555.  *
  1556.  *----------------------------------------------------------------------
  1557.  */
  1558.  
  1559.  
  1560. static void
  1561. reportError(statusPtr)
  1562. struct status    *statusPtr;
  1563. {
  1564.   int etype    = GET_ETYPE(statusPtr->status);
  1565.   int estatus    = GET_ESTATUS(statusPtr->status);
  1566.   int ecmd    = GET_ECMD(statusPtr->status);
  1567.   int ecode    = GET_ECODE(statusPtr->status);
  1568.  
  1569.   if (atcDebug){
  1570.     printf("Entered reportError.\n");
  1571.   }
  1572.  
  1573.   printf("ETYPE = %d, ESTATUS = %d, ECMD = %d, ECODE = %d\n",
  1574.      etype, estatus, ecmd, ecode);
  1575.  
  1576.  
  1577.   switch (etype){
  1578.   case ET_CMD_SPEC:
  1579.     printf("Error type ET_CMD_SPEC (command specific) \n");
  1580.     break;
  1581.   case ET_CMD_GEN:
  1582.     printf("Error type ET_CMD_GEN (generic to all host commands)\n");
  1583.     break;
  1584.   case ET_ENVIRON:
  1585.     printf("Error type ET_ENVIRON (environmental problems)\n");
  1586.     break;
  1587.   case ET_INFO:
  1588.     printf("Error type ET_INFO (informational messages for host)\n");
  1589.     break;
  1590.   case ET_BKD_DIAG:
  1591.     printf("Error type ET_BKD_DIAG (reported from bckgrnd diagnostics)\n");
  1592.     break;
  1593.   case ET_ABORT:
  1594.     printf("Error type ET_ABORT (error contains abort code #)\n");
  1595.     break;
  1596.   case ET_INIT:
  1597.     printf("Error type ET_INIT (for reporting initialization problems)\n");
  1598.     break;
  1599.   default:
  1600.     printf("Problem!!! Unrecognized error type!\n");
  1601.   }
  1602.  
  1603.  
  1604.   switch (estatus) {
  1605.   case ES_EMPTY:
  1606.     printf("Error status ES_EMPTY (no status bits active)\n");
  1607.     break;
  1608.   case ES_SENSE_VALID:
  1609.     printf("Error status ES_SENSE_VALID (sense data is valid)\n");
  1610.     break;
  1611.   case ES_NONFATAL:
  1612.     printf("Error status ES_NONFATAL (host command completed successfully)\n");
  1613.     break;
  1614.   case ES_EXT_VALID:
  1615.     printf("Error status ES_EXT_VALID (external error info is valid)\n");
  1616.     break;
  1617.   case ES_PASS_THRU:
  1618.     printf("Error status ES_PASS_THRU (to log pass-thru ops to error log)\n");
  1619.     break;
  1620.   default:
  1621.     printf("Problem!!! Unrecognized error status!\n");
  1622.   }
  1623.  
  1624.   switch (ecode) {
  1625.   case EC_CMD:
  1626.     printf("Error code EC_CMD -- invalid command in iopb\n");
  1627.     break;
  1628.   case EC_OPTION:
  1629.     printf("Error code EC_OPTION -- invalid option in iopb\n");
  1630.     break;
  1631.   case EC_PRIORITY:
  1632.     printf("Error code EC_PRIORITY -- invalid priority in iopb\n");
  1633.     break;
  1634.   case EC_LINK:
  1635.     printf("Error code EC_LINK -- invalid linked_iopb in iopb\n");
  1636.     break;
  1637.   case EC_FLAGS:
  1638.     printf("Error code EC_FLAGS -- invalid flags in iopb\n");
  1639.     break;
  1640.   case EC_ID:
  1641.     printf("Error code EC_ID -- invalid id field in iopb\n");
  1642.     break;
  1643.   case EC_LOG_BLK:
  1644.     printf("Error code EC_LOG_BLK -- invalid logical block in iopb\n");
  1645.     break;
  1646.   case EC_BYTE_CNT:
  1647.     printf("Error code EC_BYTE_CNT -- invalid byte count in iopb\n");
  1648.     break;
  1649.   case EC_BUFFER:
  1650.     printf("Error code EC_BUFFER -- invalid buffer address in iopb\n");
  1651.     break;
  1652.   case EC_BUFADDRMOD:
  1653.     printf("Error code EC_BUFADDRMOD -- invalid buf address mod in iopb\n");
  1654.     break;
  1655.   case EC_INT_LEVEL:
  1656.     printf("Error code EC_INT_LEVEL -- invalid interrupt level in iopb\n");
  1657.     break;
  1658.   case EC_AUXBUFMOD:
  1659.     printf("Error code EC_AUXBUFMOD -- invalid aux buf mod in iopb\n");
  1660.     break;
  1661.   case EC_SG_ENTRIES:
  1662.     printf("Error code EC_SG_ENTRIES -- invalid # s/g entries in iopb\n");
  1663.     break;
  1664.   case EC_AUXBUFSIZE:
  1665.     printf("Error code EC_AUXBUFSIZE -- invalid aux buffer size in iopb\n");
  1666.     break;
  1667.   case EC_AUXBUFFER:
  1668.     printf("Error code EC_AUXBUFFER -- invalid aux buff address in iopb\n");
  1669.     break;
  1670.   case EC_SG_COUNT:
  1671.     printf("Error code EC_SG_COUNT -- invalid s/g count in iopb\n");
  1672.     break;
  1673.   case EC_SG_BUFFER:
  1674.     printf("Error code EC_SG_BUFFER -- invalid s/g buffer in iopb\n");
  1675.     break;
  1676.   case EC_SG_AMOD:
  1677.     printf("Error code EC_SG_AMOD -- invalid  s/g buffer amod in iopb\n");
  1678.     break;
  1679.   default:
  1680.     printf("Problem!!! Unrecognized error code!\n");
  1681.   }
  1682. }
  1683.  
  1684.  
  1685.  
  1686.  
  1687. /*
  1688.  *----------------------------------------------------------------------
  1689.  *
  1690.  * DevATCIntr --
  1691.  *
  1692.  *    Handle interrupts from the ATC controller.   This routine
  1693.  *    may start any queued requests.
  1694.  *
  1695.  * Results:
  1696.  *    TRUE if an ATC controller was responsible for the interrupt
  1697.  *    and this routine handled it.
  1698.  *
  1699.  * Side effects:
  1700.  *    Usually a process is notified that an I/O has completed.
  1701.  *
  1702.  *----------------------------------------------------------------------
  1703.  */
  1704. Boolean
  1705. DevATCIntr(clientData)
  1706.     ClientData    clientData;
  1707. {
  1708.     ATCController    *atcPtr    = (ATCController *) clientData;
  1709.     Request        *requestPtr;
  1710.     struct iopbhdr    *iopbPtr;
  1711.     struct status    *statusPtr;
  1712.     int            index, returnVal;
  1713.     ReturnStatus    status;
  1714.     int                 error;
  1715.     
  1716.     if (atcDebug){
  1717.       printf("Entered DevATCIntr.\n");
  1718.     }
  1719.  
  1720.     /*  read fifo to get iopb index */
  1721.  
  1722.     returnVal = get_fifo(atcPtr);
  1723.     index = (returnVal & 0x7f);
  1724.     error = (returnVal & 0x100);
  1725.     if (atcDebug){
  1726.       printf("Value from get_fifo is 0x%x; index after interrupt is 0x%x\n",
  1727.          returnVal, index);
  1728.     }
  1729.  
  1730.     if (error == 0){
  1731.       if (atcDebug){
  1732.     printf("No error occurred on iopb\n");
  1733.       }
  1734.     } else {
  1735.       printf("Error in iopb!!\n");
  1736.     }
  1737.  
  1738.     iopbPtr    = &atcPtr->iopblist[index];
  1739.     statusPtr    = &atcPtr->statuslist[index];
  1740.     requestPtr    = atcPtr->requestInfo[index].requestPtr;
  1741.  
  1742.     /*
  1743.      * Release the DMA buffer if command mapped one. 
  1744.      */
  1745.     if (!VmMachIsXbusMem(atcPtr->requestInfo[index].dmaBuffer) &&
  1746.             atcPtr->requestInfo[index].dmaBufferSize > 0) {
  1747.         if (((unsigned)atcPtr->requestInfo[index].dmaBuffer) & 0x80000000) {
  1748.         VmMach_32BitDMAFree(atcPtr->requestInfo[index].dmaBufferSize, 
  1749.             atcPtr->requestInfo[index].dmaBuffer);
  1750.         } else {
  1751.         VmMach_DMAFree(atcPtr->requestInfo[index].dmaBufferSize, 
  1752.             atcPtr->requestInfo[index].dmaBuffer);
  1753.         }
  1754.     atcPtr->requestInfo[index].dmaBufferSize = 0;
  1755.     }
  1756.     bzero((char *) &(atcPtr->requestInfo[index]), sizeof(perRequestInfo));
  1757.     
  1758.     /*  
  1759.      * Need to signal error if detected 
  1760.      */
  1761.     {
  1762.     int etype    = GET_ETYPE(statusPtr->status);
  1763.     int estatus    = GET_ESTATUS(statusPtr->status);
  1764.     /*
  1765.     int ecmd    = GET_ECMD(statusPtr->status);
  1766.     int ecode    = GET_ECODE(statusPtr->status);
  1767.     */
  1768.  
  1769.  
  1770.     if (error == 0){
  1771.       status = SUCCESS;
  1772.     } else{
  1773.       switch (etype) {
  1774.       case ET_CMD_GEN:
  1775.       case ET_CMD_SPEC:
  1776.         reportError(statusPtr);
  1777.         if (estatus & ES_NONFATAL) {
  1778.           status = SUCCESS;
  1779.         } else {
  1780.           status = FAILURE;
  1781.         }
  1782.         break;
  1783.       default:
  1784.         reportError(statusPtr);
  1785.         status = FAILURE;
  1786.         break;
  1787.       }
  1788.     }
  1789.       }
  1790.   
  1791.       MASTER_LOCK(&(atcPtr->mutex));
  1792.       free_iopb(atcPtr, iopbPtr);
  1793.       MASTER_UNLOCK(&(atcPtr->mutex));
  1794.       
  1795.       RequestDone(requestPtr->diskPtr,requestPtr,status,requestPtr->numSectors);
  1796.       StartNextRequest(atcPtr);
  1797.       return(TRUE);
  1798.  
  1799.   }
  1800.  
  1801.  
  1802. /*
  1803.  *----------------------------------------------------------------------
  1804.  *
  1805.  * RequestDone --
  1806.  *
  1807.  *    Mark a request as done by calling the request's doneProc. DMA memory
  1808.  *    is released.
  1809.  *
  1810.  * Results:
  1811.  *    None.
  1812.  *
  1813.  * Side effects:
  1814.  *    None.
  1815.  *
  1816.  *----------------------------------------------------------------------
  1817.  */
  1818.  
  1819. static void
  1820. RequestDone(diskPtr, requestPtr, status, numSectors)
  1821.     ATCDisk        *diskPtr;
  1822.     Request        *requestPtr;
  1823.     ReturnStatus    status;
  1824.     int            numSectors;
  1825. {
  1826.  
  1827.   if (atcDebug){
  1828.     printf("Entered RequestDone.\n");
  1829.   }
  1830.  
  1831.     if (numSectors > 0) {
  1832.     if (requestPtr->requestPtr->operation == FS_READ) {
  1833.         diskPtr->diskStatsPtr->diskStats.diskReads++;
  1834.     } else {
  1835.         diskPtr->diskStatsPtr->diskStats.diskWrites++;
  1836.     }
  1837.     }
  1838.     (requestPtr->requestPtr->doneProc)(requestPtr->requestPtr, status,
  1839.                 numSectors*DEV_BYTES_PER_SECTOR);
  1840. }
  1841.  
  1842. /*
  1843.  *----------------------------------------------------------------------
  1844.  *
  1845.  * StartNextRequest --
  1846.  *
  1847.  *    Start the next request of an ATC controller.
  1848.  *
  1849.  * Results:
  1850.  *    None.
  1851.  *
  1852.  * Side effects:
  1853.  *    None.
  1854.  *
  1855.  *----------------------------------------------------------------------
  1856.  */
  1857. static void
  1858. StartNextRequest(atcPtr)
  1859.     ATCController *atcPtr;
  1860. {
  1861.     ATCDisk        *diskPtr;
  1862.     Request        *requestPtr;
  1863.     int            index;
  1864.  
  1865.     if (atcDebug){
  1866.       printf("Entered StartNextRequest.\n");
  1867.     }
  1868.  
  1869.      /*
  1870.       * If the controller is busy, just return.
  1871.       */
  1872.     MASTER_LOCK(&atcPtr->mutex);
  1873.     while (atcPtr->free_iopbs != NULL) {
  1874.     requestPtr = (Request *) Dev_QueueGetNextFromSet(atcPtr->ctrlQueues,
  1875.         DEV_QUEUE_ANY_QUEUE_MASK, (ClientData *) &diskPtr);
  1876.     if (requestPtr == (Request *) NIL) {
  1877.         break;
  1878.     }
  1879.     index = alloc_iopb(atcPtr)->index;
  1880.  
  1881.     MASTER_UNLOCK(&atcPtr->mutex);
  1882.     SendCommand(diskPtr, requestPtr, FALSE, index);
  1883.     MASTER_LOCK(&atcPtr->mutex);
  1884.     }
  1885.     MASTER_UNLOCK(&atcPtr->mutex);
  1886. }
  1887.